package server

import (
	"log"
	"net"
	"strings"
	"sync"
	"time"
)

//socket主服务
type SocketServer struct {
	Network             string
	Address             string                            //监听ip和端口，例如：127.0.0.1:8000
	Clients             map[string]*TcpConn               //客户端列表
	ClientTimeOutSecond int64                             //客户端超时时间，N秒没有收到客户端消息就关闭
	MaxClientNum        int                               //客户端最大连接数
	CurrentClientNum    int                               //当然客户端连接数量
	OnError             func(msg string, err error)       //发生错误
	OnStart             func(server *SocketServer)        //socket启动
	OnClientConnect     func(client *TcpConn)             //客户端连接上
	OnClientClose       func(client *TcpConn)             //与客户端关闭连接
	OnMessage           func(client *TcpConn, msg string) //接收到客户端消息
}

//启动socket
func (server *SocketServer) Start() {
	listener, err := net.Listen(server.Network, server.Address)
	if err != nil {
		server.OnError("Listen失败", err)
		return
	}
	defer listener.Close()
	log.Printf("socket 启动成功；Network=%s,Address=%s", server.Network, server.Address)
	server.OnStart(server)
	go server.CheckClient()
	for {
		conn, err := listener.Accept()
		if err != nil {
			server.OnError("Accept失败", err)
			continue
		}
		if server.CurrentClientNum >= server.MaxClientNum {
			log.Println("已经达到最大连接数了:", server.CurrentClientNum)
			conn.Close()
			continue
		}
		client := MakeClient(conn, server)
		server.OnClientConnect(client)
		server.AddClient(client)
		go client.HandleMessage()
	}
}

var mutex sync.Mutex

func (server *SocketServer) AddClient(client *TcpConn) {
	mutex.Lock()
	defer mutex.Unlock()
	server.Clients[client.Id] = client
	server.CurrentClientNum++
	log.Println("新增连接，连接数：", server.CurrentClientNum)
}

func (server *SocketServer) RemoveClient(client *TcpConn) {
	mutex.Lock()
	defer mutex.Unlock()
	if _, ok := server.Clients[client.Id]; ok {
		client.Connect.Close()
		delete(server.Clients, client.Id)
		server.OnClientClose(client)
		server.CurrentClientNum--
		log.Println("移除连接，连接数：", server.CurrentClientNum)
	}
}

func (server *SocketServer) SignPrinter(client *TcpConn, sign string) {
	mutex.Lock()
	defer mutex.Unlock()
	delete(server.Clients, client.Id)
	client.Id = sign
	server.Clients[sign] = client
	log.Println("标记打印机：", sign)
}

func (server *SocketServer) ShowClients(param string) (str string) {
	for key := range server.Clients {
		if param == "all" {
			str += key + "\n"
		} else if param == "printer" {
			if !strings.Contains(key, ".") {
				str += key + "\n"
			}
		} else if param == "pda" {
			if strings.Contains(key, ".") {
				str += key + "\n"
			}
		}
	}
	return
}

//检查超时
func (server *SocketServer) CheckClient() {
	for {
		if server.ClientTimeOutSecond < 1 {
			time.Sleep(5 * time.Second)
			continue
		}
		mutex.Lock()
		nowTime := time.Now().Unix()
		for key, value := range server.Clients {
			if nowTime-value.LastTime > server.ClientTimeOutSecond {
				value.Connect.Close()
				log.Println("移除超时客户端：", key, len(server.Clients))
			}
		}
		mutex.Unlock()
		time.Sleep(5 * time.Second)
	}
}
